/**
 * 
 */
package test;

import game.Grid;
import game.Wall;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.geom.AffineTransform;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.Timer;

/**
 * @author patrick
 * 
 */
public class LevelBuilder extends JFrame {

	private BuilderPanel panel;
	private int selectedWall;
	private int currentLevel;
	private String pathToLevels;

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		new LevelBuilder();

	}

	public LevelBuilder() {
		this.setSize(800, 600);
		this.setVisible(true);
		panel = new BuilderPanel();
		add(panel);

		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setLocationRelativeTo(null);
		setTitle("Ice Cube - Level Builder");
		setResizable(false);
		setVisible(true);

		addKeyListener(new TAdapter(this));

		pathToLevels = "src/levels/";
		currentLevel = 1;
	}

	/**
	 * @return the panel
	 */
	public BuilderPanel getPanel() {
		return panel;
	}

	/**
	 * exports the created walls to console (ready to insert in level.java)
	 * */
	public void exportWalls() {
		Wall wall;
		for (int i = 0; i < panel.getWalls().size(); i++) {
			
			wall = panel.getWalls().get(i);
			if(wall instanceof Grid)
				System.out.println("walls.add(new Grid(" + (int) wall.getX() + "," + wall.getY() + "," + wall.getWidth() + ","+ wall.getHeight() + "));");	
			else
				System.out.println("walls.add(new Wall(" + (int) wall.getX() + ","+ wall.getY() + "," + wall.getWidth() + ","+ wall.getHeight() + "));");
		}
	}

	/**
	 * saves a file for new level
	 * */
	public void saveLevel(int noOfLevel) {
		String filename = String.valueOf(noOfLevel);
		try {
			FileWriter writer = new FileWriter(pathToLevels + filename);

			Wall wall;
			for (int i = 0; i < panel.getWalls().size(); i++) {
				wall = panel.getWalls().get(i);
				// String output =
				// "walls.add(new Wall("+(int)wall.getX()+","+wall.getY()+","+wall.getWidth()+","+wall.getHeight()+"));";
				String output = wall.getValues();

				// write date about wall to file
				writer.write(output);
				writer.write("\n");
			}
			writer.close();

		} catch (IOException e) {
			System.err.println("UNABLE TO CREATE FILE");
			e.printStackTrace();
		}
	}

	/**
	 * loads selected level
	 * */
	public void loadLevel(int noOfLevel) {
		String filename = String.valueOf(noOfLevel);
		try {
			FileReader reader = new FileReader(pathToLevels + filename);
			// BufferedReader datenStrom = new BufferedReader(dateiInhalt);
			BufferedReader stream = new BufferedReader(reader);
			Scanner sc = new Scanner(stream);
			while (sc.hasNext()) {
				String output = sc.next();
				System.out.println(output);

				// : separates the walls in File
				String[] wallsInLevel = output.split(":");
				String[] tempWall = new String[3];
				Wall wallToAdd;

				// go through every wall in level
				for (int i = 0; i < wallsInLevel.length; i++) {
					// extract single line (=wall)
					tempWall = wallsInLevel[i].split(",");
					wallToAdd = new Wall(Double.valueOf(tempWall[0]), Double
							.valueOf(tempWall[1]), Double.valueOf(tempWall[2]),
							Double.valueOf(tempWall[3]));
					panel.addWall(wallToAdd);
				}
			}
		} catch (FileNotFoundException e) {
			System.err.println("FILE NOT FOUND");
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	private class BuilderPanel extends JPanel implements ActionListener {

		private ArrayList<Wall> walls;
		private JTextField noOfLevel;
		private JButton loadButton;

		public BuilderPanel() {

			walls = new ArrayList<Wall>();
			selectedWall = 0;
			this.setFocusable(true);
			this.add(new JLabel("Anleitung:"));
			this.add(new JLabel("SPACE: neues Teil"));
			this.add(new JLabel("ENTER: export ||"));
			this.add(new JLabel("ALT: teil auswählen ||"));
			this.add(new JLabel("W, A, S, D: größe verändern"));
			this.add(new JLabel("BACKSPACE: teil entfernen"));
			this.add(new JLabel("lade Level:"));
			noOfLevel = new JTextField(2);
			this.add(noOfLevel);
			noOfLevel.setText("1");

			loadButton = new JButton("go!");
			loadButton.addActionListener(new ButtonListener());
			this.add(loadButton);

			Timer t = new Timer(5, this);
			t.start();
		}

		public void paint(Graphics g) {
			super.paint(g);

			Graphics2D g2d = (Graphics2D) g;

			// draw walls of level
			for (int i = 0; i < walls.size(); i++) {

				if(walls.get(i) instanceof Grid)
					g2d.setColor(Color.lightGray);
				else
					g2d.setColor(Color.black);
				
				if (selectedWall == i)
					g2d.setColor(Color.red);
				
				AffineTransform at = AffineTransform.getRotateInstance(walls
						.get(i).getAngle(), walls.get(i).getX()
						+ walls.get(i).getWidth(), walls.get(i).getY());
				g2d.fill(at.createTransformedShape(walls.get(i)));
			}

		}

		/**
		 * @return the walls
		 */
		public ArrayList<Wall> getWalls() {
			return walls;
		}

		/**
		 * @param walls
		 *            the walls to set
		 */
		public void setWalls(ArrayList<Wall> walls) {
			this.walls = walls;
		}

		/**
		 * insert a new Wall
		 * */
		public void addWall(Wall wallToAdd) {
			this.walls.add(wallToAdd);
		}

		/**
		 * delete selected Wall
		 * */
		public void deleteWall(int wallToDelete) {
			this.walls.remove(wallToDelete);
		}

		public void actionPerformed(ActionEvent e) {
			repaint();
		}

		/**
		 * @return the noOfLevel
		 */
		public int getNoOfLevel() {
			return Integer.valueOf(noOfLevel.getText());
		}

		/**
		 * @param noOfLevel
		 *            the noOfLevel to set
		 */
		public void setNoOfLevel(int noOfLevel) {
			this.noOfLevel.setText(String.valueOf(noOfLevel));
		}

		private class ButtonListener implements ActionListener {

			public void actionPerformed(ActionEvent e) {
				loadLevel(Integer.valueOf(noOfLevel.getText()));
				
				
				panel.remove(loadButton);
			}

		}
	}

	/**
	 * customized Keylistener
	 * */
	private class TAdapter extends KeyAdapter {

		private LevelBuilder builder;

		// private BuilderPanel panel;

		public TAdapter(LevelBuilder pbuilder) {
			builder = pbuilder;
		}

		public void keyReleased(KeyEvent e) {

		}

		public void keyPressed(KeyEvent e) {
			int key = e.getKeyCode();

			if (key == KeyEvent.VK_SPACE) {
				Wall newWall = new Wall(100, 100, 100, 10);
				panel.addWall(newWall);
			}

			if (key == KeyEvent.VK_BACK_SPACE) {
				panel.deleteWall(selectedWall);
			}

			if (key == KeyEvent.VK_ALT) {
				if (panel.walls.size() == 0)
					return;
				System.out.println("ALT");
				selectedWall++;
				if (selectedWall > panel.getWalls().size())
					selectedWall = 0;
				// System.out.println("Wall selected ==" + selectedWall);
			}
			if (key == KeyEvent.VK_UP) {
				panel.getWalls().get(selectedWall).moveY(-10);
			}
			if (key == KeyEvent.VK_DOWN) {
				panel.getWalls().get(selectedWall).moveY(10);
			}
			if (key == KeyEvent.VK_LEFT) {
				panel.getWalls().get(selectedWall).moveX(-10);
			}
			if (key == KeyEvent.VK_RIGHT) {
				panel.getWalls().get(selectedWall).moveX(10);
			}
			if (key == KeyEvent.VK_S) {
				panel.getWalls().get(selectedWall).growX(5);
			}
			if (key == KeyEvent.VK_W) {
				panel.getWalls().get(selectedWall).growX(-5);
			}
			if (key == KeyEvent.VK_D) {
				panel.getWalls().get(selectedWall).growY(5);
			}
			if (key == KeyEvent.VK_A) {
				panel.getWalls().get(selectedWall).growY(-5);
			}
			if (key == KeyEvent.VK_ENTER) {
				exportWalls();
//				saveLevel(currentLevel);
			}
			if (key == KeyEvent.VK_L) {
				loadLevel(panel.getNoOfLevel());
			}
			if (key == KeyEvent.VK_SHIFT) {
				Grid newGrid = new Grid(200, 100, 50, 10);
				panel.addWall(newGrid);
			}
		}
	}

}
